package com.gl.doc.support;

import com.gl.doc.builder.WordDocument;
import com.gl.doc.model.Paragraph;
import com.gl.doc.model.SubParagraph;
import com.gl.doc.model.Word;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
 * word文档段落查找帮助工具类
 */
@Slf4j
public class ParagraphLookupSupport {
    /**
     * 根据word文档对象 {@link WordDocument}
     * 查找段落并返回一个word文档xml对象
     *
     * @param wordDocument word文档对象 {@link WordDocument}
     * @param consumer     函数式接口（消费文档段落）
     * @return word文档xml对象
     */
    public static Document paragraphLookup(WordDocument wordDocument, Consumer<Paragraph> consumer) {
        try {
            Word word = wordDocument.getWord();
            File documentFile = new File(word.getDocumentPath());
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(documentFile);
            Element rootElement = document.getRootElement();
            List<Element> elements = rootElement.elements();
            for (Element element : elements) {
                List<Element> bodyList = element.elements();
                for (Element body : bodyList) {
                    if ("p".equals(body.getName())) {
                        Paragraph paragraph = ParagraphLookupSupport.getParagraph(body, body.elements());
                        paragraph.setIdPath(elements.indexOf(element) + "," + bodyList.indexOf(body));
                        consumer.accept(paragraph);
                    } else if ("tbl".equals(body.getName())) {
                        List<Element> tbLs = body.elements();
                        for (Element tbl : tbLs) {
                            if ("tr".equals(tbl.getName())) {
                                List<Element> trs = tbl.elements();
                                for (Element tr : trs) {
                                    if ("tc".equals(tr.getName())) {
                                        List<Element> tcs = tr.elements();
                                        for (Element tc : tcs) {
                                            if ("p".equals(tc.getName())) {
                                                Paragraph paragraph = ParagraphLookupSupport.getParagraph(tc, tc.elements());
                                                paragraph.setIdPath(
                                                        elements.indexOf(element) + ","
                                                                + bodyList.indexOf(body) + ","
                                                                + tbLs.indexOf(tbl) + ","
                                                                + trs.indexOf(tr) + ","
                                                                + tcs.indexOf(tc)
                                                );
                                                consumer.accept(paragraph);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return document;
        } catch (Exception e) {
            log.error("段落获取失败!", e);
        }
        return null;
    }

    /**
     * 根据<w:p>xml元素和子元素集合<w:r>xml查找段落
     *
     * @param paragraphElement <w:p>xml元素
     * @param ps               子元素集合<w:r>xml
     * @return word文档段落 {@link Paragraph}
     */
    public static Paragraph getParagraph(Element paragraphElement, List<Element> ps) {
        Paragraph paragraph = new Paragraph();
        List<SubParagraph> subParagraphs = new ArrayList<>();
        StringBuilder pText = new StringBuilder();
        for (Element p : ps) {
            if ("r".equals(p.getName())) {
                List<Element> rs = p.elements();
                for (Element r : rs) {
                    if ("t".equals(r.getName())) {
                        String text = r.getText();
                        pText.append(text);
                        SubParagraph subParagraph = new SubParagraph();
                        subParagraph.setRElement(p);
                        subParagraph.setRIndex(ps.indexOf(p));
                        subParagraph.setTElement(r);
                        subParagraph.setTIndex(rs.indexOf(r));
                        subParagraph.setContent(text);
                        subParagraphs.add(subParagraph);
                    }
                }
            }
        }
        paragraph.setElement(paragraphElement);
        paragraph.setContent(pText.toString());
        paragraph.setSubParagraphs(subParagraphs);
        return paragraph;
    }
}
